home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 1.toast / pc / sample code / graphics 2d / thumbnail test / thumbnail.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  12.9 KB  |  514 lines

  1. /*
  2.     File:        Thumbnail.c
  3.  
  4.     Contains:    Sample to demonstrate using the Picture Utilities Package
  5.     
  6.                 The guts of this is in the window creation function: DoCreateWindow( PicHandle thePicture )
  7.     
  8.                 DoCreateWindow is passed a picture handle and if the global gUsePictPalette is set it
  9.                 will use the pict utils package (PUP) to get the color table stored in the pict.  You could 
  10.                 this source to sample direct color images, but to keep things as clear as possible this
  11.                 application only deals with 8 bit images.
  12.     
  13.                 We use the PUP to get the color table for the image.  This is passed into NewGWorld and it
  14.                 is also used to create a palette that is attached to the window.
  15.     
  16.                 Note that we use PUP to sample the image that was stored in the file.  We interrogate a
  17.                 PicHandle read directly from the file.  There are also routines for sampling PixMaps,
  18.                 but dont forget that if you are in an indexed color environment, and you sample a PixMap, 
  19.                 if you didnt set up the color environment when your first created the PixMap, the colors
  20.                 may not be as you expect.  
  21.                 
  22.                 To see an example of this there are two 8-bit images included with this snippet.
  23.                 One is a spectral ramp, the other a green/brow ramp.  Both have approx 120 or so colors.
  24.                 to see an example of what PUP may report if you didnt set the colors for a window up
  25.                 properly before displaying open one of the files with the "use picture palette" item 
  26.                 from the palette menu toggled off.
  27.     
  28.                 in this case it will use the "wrong" set of colors to try to draw the image (it just uses
  29.                 what ever the default system color table is).  If you get PUP to sample (by toggling on
  30.                 the "use picture palette" item from the palette menu the picture is rendered correctly.
  31.  
  32.     Written by: Nick Thompson    
  33.  
  34.     Copyright:    Copyright © 1994-1999 by Apple Computer, Inc., All Rights Reserved.
  35.  
  36.                 You may incorporate this Apple sample source code into your program(s) without
  37.                 restriction. This Apple sample source code has been provided "AS IS" and the
  38.                 responsibility for its operation is yours. You are not permitted to redistribute
  39.                 this Apple sample source code as "Apple sample source code" after having made
  40.                 changes. If you're going to re-distribute the source, we require that you make
  41.                 it clear in the source that the code was descended from Apple sample source
  42.                 code, but that you've made changes.
  43.  
  44.     Change History (most recent first):
  45.                 7/14/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  46.                 
  47.  
  48. */
  49.  
  50. /* Constant Declarations */
  51. #include <menus.h>
  52. #include <PictUtils.h>
  53. #include <QDOffScreen.h>
  54. #include <Fonts.h>
  55. #include <Windows.h>
  56. #include <Menus.h>
  57. #include <TextEdit.h>
  58. #include <Dialogs.h>
  59. #include <DiskInit.h>
  60. #include <StandardFile.h>
  61. #include <Devices.h>
  62.  
  63.  
  64. #define    WWIDTH        470
  65. #define    WHEIGHT        330
  66.  
  67. #define WLEFT        (((screenBits.bounds.right - screenBits.bounds.left) - WWIDTH) / 2)
  68. #define WTOP        (((screenBits.bounds.bottom - screenBits.bounds.top) - WHEIGHT) / 2)
  69.  
  70. #define HiWrd(aLong)    (((aLong) >> 16) & 0xFFFF)
  71. #define LoWrd(aLong)    ((aLong) & 0xFFFF)
  72.  
  73.  
  74.  
  75. enum {
  76.     mApple = 128,
  77.     mFile,
  78.     mPalette,
  79.     mTest
  80. } ;
  81.  
  82. enum {
  83.     iAbout = 1
  84. } ;
  85. enum {
  86.     iOpen = 1,
  87.     iClose,
  88.     iUnused1,
  89.     iQuit = 4
  90. } ;
  91.  
  92. enum {
  93.     iUsePictPalette = 1
  94. } ;
  95.  
  96. static Boolean gQuitFlag = false ;
  97.  Point gStaggerPos = {50,50} ;
  98. static Boolean gUsePictPalette = true ;
  99.  
  100. // function prototypes
  101.  
  102. void InitToolbox( void ) ;
  103. void MainEventLoop( void ) ;
  104. void HandleKeyPress(EventRecord *event) ;
  105. void HandleOSEvent(EventRecord *event) ;
  106. void HandleMenuCommand(long menuResult) ;
  107. PicHandle DoReadPICT( short theRef, OSErr *theErr ) ;
  108. OSErr DoCreateWindow( PicHandle thePicture ) ;
  109. void AdjustMenus( void ) ;
  110.  
  111.  
  112. const RGBColor    kRGBBlack = {0, 0, 0};
  113. const RGBColor    kRGBWhite = {0xFFFF, 0xFFFF, 0xFFFF};
  114.  
  115.  
  116. void main()
  117. {
  118.     InitToolbox() ;
  119.     
  120.     MainEventLoop();
  121. }
  122.  
  123.  
  124.  
  125. void InitToolbox()
  126. {
  127.     Handle        menuBar = nil;
  128.  
  129.  
  130.     InitGraf((Ptr) &qd.thePort);
  131.     InitFonts();
  132.     InitWindows();
  133.     InitMenus();
  134.     TEInit();
  135.     InitDialogs(0L);
  136.     InitCursor();
  137.  
  138.     // initialize application globals
  139.     
  140.     gQuitFlag = false;
  141.     
  142.     
  143.     menuBar = GetNewMBar(128);                // Read menus into menu bar, MBAR res id is 128
  144.     
  145.     if ( menuBar == nil )
  146.          ExitToShell();                        // if we dont have it then quit - your app 
  147.                                              // needs a dialog here
  148.  
  149.     SetMenuBar(menuBar);                    // Install menus
  150.     DisposeHandle(menuBar);
  151.     
  152.     AppendResMenu(GetMenuHandle(mApple), 'DRVR');    // Add DA names to Apple menu, ID 128
  153.  
  154.     DrawMenuBar();
  155. }
  156.  
  157.  
  158. void MainEventLoop()
  159. {
  160.     EventRecord     event;
  161.     WindowPtr       window;
  162.     short           thePart;
  163.     Rect            screenRect;
  164.     Point            aPoint = {100, 100};
  165.     GWorldPtr        theNewWorld ;
  166.     PixMapHandle    offPixMap ;
  167.     GrafPtr            oldPort ;
  168.  
  169.     while( !gQuitFlag )
  170.     {
  171.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  172.         {
  173.             AdjustMenus() ;
  174.  
  175.             switch (event.what) {
  176.                 case mouseDown:
  177.                 
  178.                     thePart = FindWindow( event.where, &window );
  179.                     
  180.                     switch( thePart ) {
  181.                         case inMenuBar: 
  182.                             HandleMenuCommand(MenuSelect(event.where));
  183.                             break;
  184.                         
  185.                         case inDrag:
  186.                     
  187.                             screenRect = (**GetGrayRgn()).rgnBBox;
  188.                             DragWindow( window, event.where, &screenRect );
  189.                             break ;
  190.                     
  191.                         case inContent:
  192.                     
  193.                             if (window != FrontWindow())
  194.                                 SelectWindow( window );
  195.                             break ;
  196.                     
  197.                         case inGoAway:
  198.                             if (TrackGoAway( window, event.where )) {
  199.                                 DisposeWindow ( window );
  200.                             }
  201.                             break ;
  202.                             
  203.                         default:
  204.                             break ;
  205.                     }
  206.                     break ;
  207.                             
  208.                         
  209.                 case updateEvt:
  210.                 
  211.                     window = (WindowPtr)event.message;
  212.                     GetPort(&oldPort ) ;    
  213.                     SetPort( window );
  214.                     
  215.                     BeginUpdate( window );
  216.                     
  217.                     // get the GWorld from the window refcon
  218.                     theNewWorld = (GWorldPtr)GetWRefCon ( window );
  219.                     offPixMap = GetGWorldPixMap( theNewWorld ) ;
  220.                     (void) LockPixels( offPixMap ) ;
  221.                     CopyBits( &((GrafPtr)theNewWorld)->portBits,
  222.                               &window->portBits,
  223.                               &window->portRect,
  224.                               &window->portRect,
  225.                               srcCopy,
  226.                               nil ) ;
  227.                     (void) UnlockPixels( offPixMap ) ;
  228.  
  229.                     EndUpdate( window );
  230.                     SetPort( oldPort ) ;
  231.                     break ;
  232.                     
  233.                 case keyDown:
  234.                 case autoKey:
  235.                     HandleKeyPress(&event);
  236.                     break;
  237.                     
  238.                 case diskEvt:
  239.                     if ( HiWrd(event.message) != noErr ) 
  240.                         (void) DIBadMount(aPoint, event.message);
  241.                     break;
  242.                     
  243.                 case osEvt:
  244.                 case activateEvt:
  245.                     break;
  246.  
  247.  
  248.             }
  249.         }
  250.     }
  251. }
  252.  
  253.  
  254. void HandleKeyPress(EventRecord *event)
  255. {
  256.     char    key;
  257.  
  258.     key = event->message & charCodeMask;
  259.     
  260.     // just check to see if we want to quit...
  261.     
  262.     if ( event->modifiers & cmdKey ) {        /* Command key down? */
  263.         HandleMenuCommand(MenuKey(key));
  264.     } 
  265. }
  266.  
  267.  
  268. void HandleMenuCommand(long menuResult)
  269. {
  270.     short        menuID;
  271.     short        menuItem;
  272.     Str255        daName;
  273.     DialogPtr    theDialog ; 
  274.     short        itemHit ;
  275.     SFTypeList    myTypes = { 'PICT' } ;
  276.     PicHandle    thePicture ;
  277.     OSErr        err ;
  278.     short        theRef ;
  279.     
  280.     StandardFileReply    theSFReply ;
  281.  
  282.     menuID = HiWrd(menuResult);
  283.     menuItem = LoWrd(menuResult);
  284.     switch ( menuID ) {
  285.         case mApple:
  286.             switch ( menuItem ) {
  287.                 case iAbout:
  288.                     theDialog = GetNewDialog ( 128, nil, (WindowPtr)-1 );
  289.                     do {
  290.                         ModalDialog ( nil, &itemHit );
  291.                     } while( itemHit != ok ) ;
  292.                     DisposeDialog ( theDialog );
  293.                     break;
  294.                     
  295.                 default:
  296.                     GetMenuItemText(GetMenuHandle(mApple), menuItem, daName);
  297.                     (void) OpenDeskAcc(daName);
  298.                     break;
  299.             }
  300.             break;
  301.         case mFile:
  302.             switch ( menuItem ) {
  303.                 case iOpen:
  304.                     // Get the file name to open
  305.                     StandardGetFile( nil, 1, myTypes, &theSFReply ) ;
  306.                     
  307.                     // did the user cancel?
  308.                     if(!theSFReply.sfGood)
  309.                         break ;
  310.                     
  311.                     // open the file
  312.                     err = FSpOpenDF( &theSFReply.sfFile, fsRdPerm, &theRef ) ;
  313.                     
  314.                     if( err != noErr )
  315.                         break ;     // should handle this properly
  316.                         
  317.                     thePicture = DoReadPICT( theRef, &err ) ;
  318.                     
  319.                     if( err != noErr )
  320.                         break ;     // should handle this properly
  321.                 
  322.                     // display the contents
  323.                     err = DoCreateWindow( thePicture ) ;
  324.                     
  325.                     break ;
  326.                     
  327.                 case iClose:
  328.                     DisposeWindow ( FrontWindow() );
  329.                     break ;
  330.                 case iQuit:
  331.                     gQuitFlag = true;
  332.                     break;
  333.             }
  334.             break;
  335.             
  336.         case mPalette:
  337.             switch ( menuItem ) {
  338.                 case iUsePictPalette :
  339.                     // toggle the check mark and the global boolean
  340.                     gUsePictPalette = !gUsePictPalette ;
  341.                     CheckItem ( GetMenuHandle ( mPalette ), iUsePictPalette, gUsePictPalette );
  342.                     break ;
  343.             }
  344.             break ;
  345.             
  346.         case mTest:
  347.         
  348. //--------------------------- T E S T   R O U T I N E ---------------------------------
  349.             if( menuItem == 1 ) {
  350.                 // get some of the screen
  351.                 void ShrinkToBWPict( WindowPtr theWindow ) ;        // prototype
  352.                 
  353.                 // because I have multiple monitors and I wanted to test on them
  354.                 // I set up the area below, you may want something rather different
  355.                 // YOU WILL PROBABLY NEED TO CHANGE THIS
  356.                 
  357.                 Rect area = { 0, -50, 200, 200 } ;                // area to save 
  358.  
  359.                 ShrinkToBWPict( FrontWindow() ) ;
  360.                 
  361.                 
  362. //--------------------------- T E S T   R O U T I N E ---------------------------------
  363.  
  364.             }
  365.             break; 
  366.  
  367.     }
  368.     HiliteMenu(0);        // Unhighlight whatever MenuSelect or MenuKey hilited
  369. }
  370.  
  371. void AdjustMenus( void ) 
  372. {
  373.     WindowPtr    theWindow ;
  374.     theWindow = FrontWindow() ;
  375.     if( theWindow != nil ) {
  376.         EnableItem ( GetMenuHandle ( mFile ), iClose );
  377.         EnableItem ( GetMenuHandle ( mTest ), 0 );    // <== 0 is entire menu
  378.     }
  379.     else {
  380.         DisableItem ( GetMenuHandle ( mFile ), iClose );
  381.         DisableItem ( GetMenuHandle ( mTest ), 0 );    // <== 0 is entire menu
  382.     }
  383.     // make sure the check marks are correct
  384.     CheckItem ( GetMenuHandle ( mPalette ), iUsePictPalette, gUsePictPalette );
  385. }
  386.  
  387. PicHandle DoReadPICT( short theRef, OSErr *theErr ) 
  388. {
  389.     long        theFileSize ;
  390.     PicHandle    thePicture ;
  391.     
  392.     // pict files have a 512 byte header at the front - we dont care about this
  393.     // we can find the size of the pict by subtracting 512 bytes from the length
  394.     // of the file.  We then want to resize the handle to that and read the data
  395.     // into the resized handle.
  396.     
  397.     if(( *theErr = GetEOF( theRef, &theFileSize )) != noErr ) {
  398.         FSClose( theRef ) ;
  399.         return nil ; 
  400.     }
  401.     
  402.     if(( *theErr = SetFPos( theRef, fsFromStart, 512)) != noErr ) {
  403.         FSClose( theRef ) ;
  404.         return nil ; 
  405.     }
  406.  
  407.     theFileSize -= 512 ;
  408.     
  409.     thePicture = (PicHandle)NewHandle( theFileSize ) ;
  410.     if( thePicture == nil ) {
  411.         FSClose( theRef ) ;
  412.         *theErr = MemError() ;
  413.         return nil ;         // what ever the mem manager error was
  414.     }
  415.     
  416.     HLock( (Handle)thePicture ) ;
  417.     *theErr = FSRead( theRef, &theFileSize, (Ptr)*thePicture ) ;
  418.     HUnlock(  (Handle)thePicture ) ;
  419.     
  420.     if( *theErr != noErr ) {
  421.         FSClose( theRef ) ;
  422.         return nil ; 
  423.     }
  424.  
  425.     return thePicture ;    
  426. }
  427.  
  428. OSErr DoCreateWindow( PicHandle thePicture )
  429. {
  430.  
  431.     Rect        theRect ;
  432.     OSErr        theErr ;
  433.     GWorldPtr    theNewWorld ;
  434.     CGrafPtr    savedPort ;
  435.     WindowPtr    theWindow ;
  436.     GDHandle    oldDevice ;
  437.     
  438.     PictInfo        thePictInfo ;
  439.     PaletteHandle    thePictPalette = nil ;
  440.     CTabHandle        thePictCTab = nil ;
  441.     
  442.     // make an offscreen environment and image the pict into this
  443.     // Make a window the size of the pict
  444.     // store a reference to the GWorld in the Refcon of the window
  445.     // invalidate the window content area.
  446.     
  447.     theRect = (**thePicture).picFrame;
  448.     
  449.     // to we want to attempt to sample the picture... 
  450.     if( gUsePictPalette ) {
  451.     
  452.         // use the picture utilities to get the palette for the window
  453.         theErr = GetPictInfo( thePicture, &thePictInfo, returnColorTable, 256, systemMethod, 0) ;
  454.         
  455.         // set up the palette and color table for later use
  456.         thePictPalette = NewPalette( 256, thePictInfo.theColorTable, pmTolerant, 0x1000 ) ;
  457.         thePictCTab = thePictInfo.theColorTable ;
  458.     }
  459.     
  460.     // we are only dealing with eight bit images here
  461.     // hence the requirement for the picture utils package to 
  462.     // return 256 colors, and we will create a gWorld 8 bits deep
  463.     
  464.     theErr = NewGWorld( &theNewWorld, 8, &theRect, thePictCTab, nil, 0L ) ;
  465.     
  466.     if( theErr != noErr ) 
  467.         return theErr ;
  468.     
  469.     // save the world
  470.     GetGWorld( &savedPort, &oldDevice ) ;
  471.     SetGWorld( theNewWorld, nil ) ;
  472.     
  473.     
  474.     RGBForeColor( &kRGBBlack ) ;        // ensure the fg and bg colors are 
  475.     RGBBackColor( &kRGBWhite ) ;        // as anticipated
  476.     EraseRect( &theRect ) ;                // clear the area for the pict
  477.     PenMode( srcCopy ) ;                // ensure the t/f mode is as expected
  478.  
  479. SetOrigin( theRect.left, theRect.top );
  480.  
  481.     
  482.     // render the image into the offscreen buffer
  483.     DrawPicture( thePicture, &theRect ) ;
  484. SetOrigin( 0, 0 );
  485.     
  486.     SetGWorld( savedPort, oldDevice ) ;
  487.     
  488.     // create the window
  489.     OffsetRect( &theRect, gStaggerPos.h, gStaggerPos.v) ;
  490.     gStaggerPos.h += 16 ;
  491.     gStaggerPos.v += 16 ;        // heh - should roll these around, but you wont 
  492.                                 // create more than a couple of windows, will you  :-)
  493.                                  
  494.     theWindow  = NewCWindow( nil, &theRect, "\pplayTime", true, 
  495.                                 documentProc, (WindowPtr)-1, true, (long)theNewWorld );    
  496.                 
  497.     // and if we set up the palette earlier assign it to the window                
  498.     if( thePictPalette != nil ) {
  499.         SetPalette ( theWindow, thePictPalette, true );
  500.     }
  501.     
  502.     ActivatePalette ( theWindow );    
  503.     
  504.     // make sure it is visible
  505.     ShowWindow( theWindow ) ;
  506.     
  507.     SetGWorld( (CGrafPtr)theWindow, nil ) ;
  508.     
  509.     // invalidate the content region of the window - we don't do any drawing to it here.
  510.     InvalRect ( &theRect );
  511.     
  512.     SetGWorld( savedPort, oldDevice ) ;
  513.     return noErr;
  514. }